﻿using System;
using System.Collections.Generic;
using System.Windows;

namespace BeerManagementSystem
{
    internal class Backend
    {
        //
        private SQLConnector _sqlConnector;

        public Backend()
        {
            _sqlConnector = new SQLConnector();

            Ranking.UpdateCurrentDate();
            if (Ranking.IsNotToday(_sqlConnector.GetLastTransactionDateTime()))
            {
                _sqlConnector.ResetBeerDay();

                if (Ranking.IsNewMonth(_sqlConnector.GetLastTransactionDateTime()))
                    _sqlConnector.ResetBeerMonth();
            }
            UpdateTotalCounters();
        }

        public User GetUserByCardId(int cardId)
        {
                return _sqlConnector.GetUser(cardId);
        }

        public User GetUser(int id)
        {
            return _sqlConnector.GetUserById(id);
        }

        internal Transaction GetLastTransaction(User user)
        {
                return _sqlConnector.GetLastTransaction(user);
        }

        internal Transaction GetLastTransaction()
        {
            return _sqlConnector.GetLastTransaction();
        }

        internal void WriteTransaction(User currentUser, byte transactionType, Drink drink)
        {
            switch (drink)
            {
                case Drink.Wine: // Wein
                    if (transactionType == 2) break;
                    _sqlConnector.AddToAccountOther(currentUser, 1.5);
                    break;
                case Drink.Shot: // Schnaps
                    if (transactionType == 2) break;
                    _sqlConnector.AddToAccountOther(currentUser, 0.5);
                    break;
                case Drink.Beer: // Bier
                    if (transactionType == 3) break;
                    Ranking.IncrementBeerTotalCount();
                    // Userbieranzahl in der Datenbank um 1 erhoehen
                    _sqlConnector.IncrementUserBeer(currentUser);
                    
                    break;
            }
            // Aufenthaltsdauer aktualisieren
            TimeSpan span = (DateTime.Now - _sqlConnector.GetLastTransactionDateTime(currentUser));

            if (!Ranking.IsNotToday(_sqlConnector.GetLastTransactionDateTime(currentUser)))
            {
                _sqlConnector.IncreaseDuration(currentUser, Math.Round((decimal)(span.TotalHours), 3));
            }
            _sqlConnector.WriteTransaction(currentUser, transactionType, drink);
#if DEBUG
            
#endif
        }



        internal bool CheckLiquidity(User currentUser)
        {
            //todo aus config auslesen
            return _sqlConnector.IsLiquid(currentUser, 15);
        }

        internal Ranking GetRanking(int countTotal, int countMonth, int countDay)
        {
            Ranking ranking = new Ranking(countTotal,countMonth,countDay);
            ranking.SetRankingTotal(_sqlConnector.GetRankingTotal(countTotal));
            ranking.SetRankingMonth(_sqlConnector.GetRankingMonth(countMonth));
            ranking.SetRankingDay(_sqlConnector.GetRankingDay(countDay));
            UpdateTotalCounters();
            return ranking;
        }

        private void UpdateTotalCounters()
        {
            Ranking.SetTotalBeerCount(_sqlConnector.GetTotalBeerCount());
            Ranking.SetMonthBeerCount(_sqlConnector.GetMonthBeerCount());
            Ranking.SetDayBeerCount(_sqlConnector.GetDayBeerCount());
        }

        public User GetCurrentUser()
        {
            return _sqlConnector.GetLastTransaction().User;
        }

        public int GetUserRank(User currentUser)
        {
            return _sqlConnector.GetUserRank(currentUser);
        }


        public Beerdocter GetBeerDocterProfile(int no)
        {
            return _sqlConnector.GetBeerdocter(no);
        }

        public int GetBeerDocterCount()
        {
            return _sqlConnector.GetBeerDocterCount();
        }

        internal void IncreaseBarrel()
        {
            Properties.Settings.Default.BarrelFillnessStatus += 1;
            Properties.Settings.Default.Save();
        }

        internal void ResetBarrel()
        {
            Properties.Settings.Default.BarrelFillnessStatus = 0;
            Properties.Settings.Default.Save();
        }
        
        internal void DeleteLastTransaction()
        {
            Transaction lt = GetLastTransaction();
            User las = lt.User;
            if (lt.Type == 3)
            {
                switch ((Drink)lt.Drink_Type)
                {
                    case Drink.Beer:
                        _sqlConnector.DeleteLastTransaction();
                        _sqlConnector.DecrementUserBeer(GetLastTransaction().User);
                        Ranking.DecrementBeerTotalCount();
                        Properties.Settings.Default.BarrelFillnessStatus--;
                        Properties.Settings.Default.Save();
                        _sqlConnector.DeleteLastTransaction();
                        break;
                    case Drink.Shot: 
                        _sqlConnector.AddToAccountOther(lt.User,-0.5);
                        _sqlConnector.DeleteLastTransaction();
                        _sqlConnector.DeleteLastTransaction();
                        break;
                    case Drink.Wine:
                        _sqlConnector.AddToAccountOther(lt.User,-1.5);
                        _sqlConnector.DeleteLastTransaction();
                        _sqlConnector.DeleteLastTransaction();
                        break;
                }
            }
            else
            {
                switch ((Drink) lt.Drink_Type)
                {
                    case Drink.Beer:
                        _sqlConnector.DecrementUserBeer(lt.User);
                        Ranking.DecrementBeerTotalCount();
                        _sqlConnector.DeleteLastTransaction();
                        break;
                    case Drink.Shot:
                        _sqlConnector.AddToAccountOther(lt.User, -0.5);
                        _sqlConnector.DeleteLastTransaction();
                        break;
                    case Drink.Wine:
                        _sqlConnector.AddToAccountOther(lt.User, -1.5);
                        _sqlConnector.DeleteLastTransaction();
                        break;
                }
                //Aufenthaltsdauer zurücksetzen 
                Transaction pre = GetLastTransaction(las);
                if (!Ranking.IsNotToday(pre.Timestamp))
                    _sqlConnector.IncreaseDuration(las, -Math.Round((decimal)(lt.Timestamp - pre.Timestamp).TotalHours, 3));
            
                
            }
        }

        internal string[] GetUserNames()
        {
            return _sqlConnector.GetUserNames();
        }

        public bool AssignUserToCard(string fullName, int cardId)
        {
            string[] name = fullName.Split(' ');
            
            string pre = (name.Length < 3) ? name[0] : name[0] + " " + name[1];
            string last = (name.Length < 3) ? name[1] : name[2];

            if (_sqlConnector.GetUser(pre, last) == null) return false;
            _sqlConnector.SetUserToCard(_sqlConnector.GetUser(pre, last),cardId); 
            return true;
        }

        public void AssignUserToCard(User currentUser, int cardId)
        {
            _sqlConnector.SetUserToCard(currentUser, cardId);
        }

        public void CreateUser(string assigningName)
        {
            string[] name = assigningName.Split(' ');

            string pre = (name.Length < 3) ? name[0] : name[0] + " " + name[1];
            string last = (name.Length < 3) ? name[1] : name[2];

            _sqlConnector.CreateUser(pre, last);
        }

        public bool QuestionUserExists(string assigningName)
        {
            string[] name = assigningName.Split(' ');

            string pre = (name.Length < 3) ? name[0] : name[0] + " " + name[1];
            string last = (name.Length < 3) ? name[1] : name[2];

            return (_sqlConnector.GetUser(pre, last) != null);
        }

        public List<User> GetAllUsers()
        {
            return _sqlConnector.GetAllUsers();
        }

        internal void ManagingBeerbillAccount(DateTime date)
        {
            _sqlConnector.UpdateBeerbillAccount(date);
        }

        internal void Missmach()
        {
            _sqlConnector.MissMatch();
        }

        public void test()
        {
            _sqlConnector.test();
        }

        public void UpdateUser(User user)
        {
            _sqlConnector.UpdateUser(user);
        }

        internal int GetCardType(int p)
        {
            return _sqlConnector.GetCardType(p);
        }

        public void ResetGuestCards()
        {
            _sqlConnector.ResetGuestCards();
        }

        public void SetCardType(int type, int cardId)
        {
            _sqlConnector.SetCardType(type,cardId);
        }



        internal void GameCdWon(User u, decimal p)
        {
            _sqlConnector.IncreaseUserGameAccount(u,p);
            _sqlConnector.AddToAccountBeerbill(u, p);
        }
    }
}
